package com.bii.gelapp;

import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Hashtable;

import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class SegmentationActivity extends Activity {
	String analysisorigin = "";
	public Bitmap originalBmp; // origin
	public static Bitmap activeBmp; // edited image
	public static Bitmap takenBmp;
	public static Bitmap grayBmp;
	ImageView ivImage, ivLoading;
	EditText etMinsize;
	Button btEdge, btPrev, btCompare;
	public static int minsize = 450;
	// 24/7 arraylist of connectedcomponents
	ArrayList<ConnectedComponent> componentlist = new ArrayList<ConnectedComponent>();
	ArrayList<ConnectedComponent> markerlist = new ArrayList<ConnectedComponent>();

	// 15 september
	ArrayList<ConnectedComponent> addedcomponentlist = new ArrayList<ConnectedComponent>();

	Mat destImg;

	int sigmatochange = 12;

	int counterup = 0;
	int counterdown = 0;
	ProgressDialog dialog;

	Bitmap segmentedBmp;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.segmentationactivity);
		
		// instructions
		String donotshow = "";
		final Dialog instructiondialog = new Dialog(SegmentationActivity.this);
		instructiondialog.setContentView(R.layout.instructiondialog);
		instructiondialog.setTitle("Attention");
		instructiondialog.setCancelable(true);
		instructiondialog.setCancelable(false);

		TextView tvInstructions = (TextView) instructiondialog
				.findViewById(R.id.tvInstructions);
		ImageView imgView = (ImageView) instructiondialog
				.findViewById(R.id.ivInstructions);
		final CheckBox donotshowbox = (CheckBox) instructiondialog.findViewById(R.id.donotshow);
		Button btOk = (Button) instructiondialog.findViewById(R.id.btOk);

		final SharedPreferences donotshowinstructions = this.getSharedPreferences(
				"instructions", 0);
		donotshow = donotshowinstructions.getString("segmentationinstructions",
				"nothing");
		if (donotshow.equals("nothing")) {
			donotshow = "Show";
		}

		if (donotshow.equals("Show")) {
			tvInstructions.setText("Enter the minimum size of fragments, in pixels, for detection");
			
			Drawable drawable = getResources().getDrawable(R.drawable.segmentation_instructions);

			Bitmap instructionbmp = ((BitmapDrawable)drawable).getBitmap();
			
			imgView.setImageBitmap(instructionbmp);
			
			instructiondialog.show();

			btOk.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					if(donotshowbox.isChecked()){
						SharedPreferences.Editor editor = donotshowinstructions.edit();
						editor.putString("segmentationinstructions", "DoNotShow");
						editor.commit();
					}
					else
					{
						SharedPreferences.Editor editor = donotshowinstructions.edit();
						editor.putString("segmentationinstructions", "Show");
						editor.commit();
					}
					instructiondialog.dismiss();
				}
			});
			
		}
		//
		
		if (getIntent().hasExtra("analysisorigin")) {
			analysisorigin = getIntent().getStringExtra("analysisorigin");
		}
		
		
		LinearLayout myLayout = (LinearLayout) findViewById(R.id.segmentationlayout);
		myLayout.requestFocus();
		ivImage = (ImageView) findViewById(R.id.ivImage);
		ivImage.setEnabled(false);
		byte[] byteArray = getIntent().getByteArrayExtra("BMP");
		originalBmp = BitmapFactory.decodeByteArray(byteArray, 0,
				byteArray.length);

		// componentlist and markerlist edited
		if (getIntent().hasExtra("componentlist")) {
			ArrayList<ConnectedComponent> componentlistedited = (ArrayList<ConnectedComponent>) getIntent()
					.getSerializableExtra("componentlist");
			if (componentlistedited.size() != 0) {
				componentlist.clear();
				// Collections.copy(componentlist, componentlistedited);
				for (int i = 0; i < componentlistedited.size(); i++) {
					componentlist.add(componentlistedited.get(i));
				}
			}
		}

		if (getIntent().hasExtra("markerlist")) {
			ArrayList<ConnectedComponent> markerlistedited = (ArrayList<ConnectedComponent>) getIntent()
					.getSerializableExtra("markerlist");

			if (markerlistedited.size() != 0) {
				markerlist.clear();

				// Collections.copy(markerlist, markerlistedited);
				for (int i = 0; i < markerlistedited.size(); i++) {
					markerlist.add(markerlistedited.get(i));
				}
			}
		}

		// from fullscreen
		if (getIntent().hasExtra("activeBmp")) {
			byte[] byteArrayActive = getIntent().getByteArrayExtra("activeBmp");
			if (byteArrayActive.length != 0) {
				activeBmp = BitmapFactory.decodeByteArray(byteArrayActive, 0,
						byteArrayActive.length);
				// Bitmap resizedbmp = Bitmap.createScaledBitmap(activeBmp, 300,
				// 300, true);
				// ivImage.setImageBitmap(resizedbmp);
				ivImage.setImageBitmap(activeBmp);
			} else {
				activeBmp = originalBmp;
				// Bitmap resizedbmp = Bitmap.createScaledBitmap(originalBmp,
				// 300,
				// 300, true);
				// ivImage.setImageBitmap(resizedbmp);
				ivImage.setImageBitmap(activeBmp);
			}
		} else {
			activeBmp = originalBmp;
			// Bitmap resizedbmp = Bitmap.createScaledBitmap(originalBmp, 300,
			// 300, true);
			// ivImage.setImageBitmap(resizedbmp);
			ivImage.setImageBitmap(activeBmp);
		}

		etMinsize = (EditText) findViewById(R.id.etMinsize);
		//etMinsize.setText("" + 450);
		etMinsize.setHint("size to segment fragments");

		btEdge = (Button) findViewById(R.id.btEdge);

		btEdge.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				dialog = ProgressDialog.show(SegmentationActivity.this,
						"Loading", "Please wait");

				Thread th = new Thread(new Runnable() {

					@Override
					public void run() {

						// TODO Auto-generated method stub
						// TODO Auto-generated method stub
						boolean progress = false;

						takenBmp = originalBmp;
						Mat srcImg = new Mat(takenBmp.getHeight(), takenBmp
								.getWidth(), CvType.CV_8U, new Scalar(4));
						int ch = srcImg.channels();
						Utils.bitmapToMat(takenBmp, srcImg);
						Imgproc.cvtColor(srcImg, srcImg, Imgproc.COLOR_BGR2GRAY);
						ch = srcImg.channels();
						ArrayList<ConnectedComponent> connectedComponentList = new ArrayList<ConnectedComponent>();
						destImg = new Mat();
						Imgproc.cvtColor(srcImg, destImg,
								Imgproc.COLOR_GRAY2BGR);

						int w = srcImg.width();
						int h = srcImg.height();

						minsize = Integer.parseInt(etMinsize.getText()
								.toString());
						componentlist.clear();
						connectedComponentList.clear();
						markerlist.clear();
						findConnectedComponents(srcImg, destImg,
								connectedComponentList, minsize);

						Collections.sort(componentlist,
								new Comparator<ConnectedComponent>() {
									@Override
									public int compare(ConnectedComponent cc1,
											ConnectedComponent cc2) {
										return cc1.left - cc2.left;
									}
								});

						// grey img
						grayBmp = RotationActivity.colorBmp.copy(
								Config.ARGB_8888, true);
						srcImg = new Mat(grayBmp.getHeight(), grayBmp
								.getWidth(), CvType.CV_8U, new Scalar(4));
						Bitmap myBitmap32 = grayBmp.copy(
								Bitmap.Config.ARGB_8888, true);
						Utils.bitmapToMat(myBitmap32, srcImg);
						Imgproc.cvtColor(srcImg, destImg,
								Imgproc.COLOR_BGR2GRAY);
						// grayBmp = Bitmap.createBitmap(destImg.cols(),
						// destImg.rows(),
						// Bitmap.Config.RGB_565);
						Utils.matToBitmap(destImg, grayBmp);
						fixRectangles();
						// fixRectangles3();

						MarkerStandard ms = StartActivity.ms;
						/*
						 * // 15 september, long fragment algorithm int
						 * medianfragnum = ms.getmarkers().size();
						 * ArrayList<ConnectedComponent> medianfragments = new
						 * ArrayList<ConnectedComponent>(); for (int i = 0; i <
						 * medianfragnum; i++) {
						 * medianfragments.add(componentlist.get(i)); }
						 * Collections.sort(medianfragments, new
						 * Comparator<ConnectedComponent>() {
						 * 
						 * @Override public int compare(ConnectedComponent cc1,
						 * ConnectedComponent cc2) { return ((cc1.right -
						 * cc1.left) - (cc2.right - cc2.left)); } });
						 * 
						 * for (int i = 0; i < medianfragments.size(); i++) {
						 * Log.d("tag1", "median widths: " +
						 * (medianfragments.get(i).right - medianfragments
						 * .get(i).left)); } int medianwidth =
						 * medianfragments.get(medianfragments .size() /
						 * 2).right - medianfragments.get(medianfragments.size()
						 * / 2).left;
						 * 
						 * for (int i = 0; i < componentlist.size(); i++) {
						 * fixLongfragments(medianwidth, componentlist.get(i));
						 * }
						 * 
						 * for (int i = 0; i < addedcomponentlist.size(); i++) {
						 * componentlist.add(addedcomponentlist.get(i)); }
						 * 
						 * // 15 september, long fragment algorithm
						 */

						ArrayList<ConnectedComponent> componentmarkers = new ArrayList<ConnectedComponent>();

						if (ms.getmarkers().size() < componentlist.size()) {
							for (int i = 0; i < ms.getmarkers().size() + 1; i++) {
								// for (int i = 0; i < 8; i++) {
								componentmarkers.add(componentlist.get(i));
							}

						}

						double graphaverage = 9999;
						double thresholdvalue = 30;

						Point pt1 = null;
						Point pt2 = null;

						while (graphaverage > thresholdvalue) {
							graphaverage = 0;
							ConnectedComponent mincc = new ConnectedComponent();
							mincc.top = 9999;

							ConnectedComponent maxcc = new ConnectedComponent();
							maxcc.top = 0;

							for (int i = 0; i < componentmarkers.size(); i++) {
								if (componentmarkers.get(i).top < mincc.top) {
									mincc = componentmarkers.get(i);
								}
								if (componentmarkers.get(i).top > maxcc.top) {
									maxcc = componentmarkers.get(i);
								}
							}

							// formula of line
							double m1 = 0, m2 = 0, m3 = 0, m4 = 0;
							for (int i = 0; i < componentmarkers.size(); i++) {
								double mlx = (componentmarkers.get(i).left + componentmarkers
										.get(i).right) / 2;
								double mly = (componentmarkers.get(i).top + componentmarkers
										.get(i).bottom) / 2;
								// m1 += mlx * mlx;
								// m2 += mlx * mly;
								// m3 += mlx;
								// m4 += mly;
								m1 += mly * mly;
								m2 += mlx * mly;
								m3 += mly;
								m4 += mlx;
							}

							double XMean = m3 / componentmarkers.size();
							double YMean = m4 / componentmarkers.size();
							double formulaA = (m2 - m3 * YMean)
									/ (m1 - m3 * XMean);
							double formulaB = YMean - formulaA * XMean;

							int firstx = (mincc.left + mincc.right) / 2;
							int firsty = (mincc.top + mincc.bottom) / 2;
							int lastx = (maxcc.left + maxcc.right) / 2;
							int lasty = (maxcc.top + maxcc.bottom) / 2;

							double bestfity1 = firsty;
							double bestfitx1 = formulaA * bestfity1 + formulaB;// (bestfity1
																				// -
																				// formulaB)
																				// /
																				// formulaA;
							double bestfity2 = lasty;
							double bestfitx2 = formulaA * bestfity2 + formulaB;// (bestfity2
																				// -
																				// formulaB)
																				// /
																				// formulaA;

							pt1 = new Point(bestfitx1, bestfity1);
							pt2 = new Point(bestfitx2, bestfity2);
							for (int i = componentmarkers.size() - 1; i > -1; i--) {

								double jx = (componentmarkers.get(i).left + componentmarkers
										.get(i).right) / 2;
								double jy = (componentmarkers.get(i).top + componentmarkers
										.get(i).bottom) / 2;

								// double jbestfitx = (jy - formulaB) /
								// formulaA;
								double jbestfitx = formulaA * jy + formulaB;
								;
								double componentaverage = Math.abs(jx
										- jbestfitx);
								graphaverage += componentaverage;
							}

							if (graphaverage > thresholdvalue) {
								Log.d("tag1",
										"deleted: "
												+ (componentmarkers.size() - 1));
								componentmarkers.remove(componentmarkers.size() - 1);
							}

							Core.line(destImg, pt1, pt2,
									new Scalar(255, 0, 255), 5);

						}

						for (int i = 0; i < componentmarkers.size(); i++) {

							markerlist.add(componentmarkers.get(i));
						}

						Log.d("tag1", "markerlist size: " + markerlist.size());

						for (int i = markerlist.size() - 1; i >= 0; i--) {
							componentlist.remove(i);
						}

						// Core.line(destImg, pt1, pt2, new Scalar(255, 0, 0),
						// 5);
						Bitmap drawnbmp = Bitmap.createBitmap(destImg.cols(),
								destImg.rows(), Bitmap.Config.RGB_565);
						Utils.matToBitmap(destImg, drawnbmp);

						Bitmap segmentedBmp = Bitmap.createBitmap(
								destImg.cols(), destImg.rows(),
								Bitmap.Config.RGB_565);
						Utils.matToBitmap(destImg, segmentedBmp);
						activeBmp = segmentedBmp;

						// ivImage.setEnabled(true);
						// btCompare.setEnabled(true);

						grayBmp = RotationActivity.colorBmp.copy(
								Config.ARGB_8888, true);
						Utils.bitmapToMat(grayBmp, destImg);

						drawRectangles();
						Utils.matToBitmap(destImg, grayBmp);
						activeBmp = grayBmp;
						// Utils.matToBitmap(destImg, grayBmp);
						// Bitmap resizedbmp1 =
						// Bitmap.createScaledBitmap(grayBmp, 300,
						// 300, true);
						// ivImage.setImageBitmap(segmentedBmp);
						dialog.dismiss();

						runOnUiThread(new Runnable() // run on ui thread
						{

							@Override
							public void run() {

								ivImage.setImageBitmap(activeBmp);

							}

						});

					}
				});
				th.start();
				ivImage.setEnabled(true);
				btCompare.setEnabled(true);

			}

		});

		ivImage.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent goToNextActivity = new Intent(getApplicationContext(),
						FullscreenActivity.class);
				byte[] bytes;
				/*
				 * if (activeBmp == null) { bytes = compressImage(originalBmp);
				 * } else { bytes = compressImage(activeBmp); }
				 */
				bytes = compressImage(originalBmp);
				goToNextActivity.putExtra("BMP", bytes);
				byte[] bytes2;
				/*
				 * if (activeBmp == null) { bytes = compressImage(originalBmp);
				 * } else { bytes = compressImage(activeBmp); }
				 */
				bytes2 = compressImage(activeBmp);
				goToNextActivity.putExtra("BMP2", bytes2);

				goToNextActivity.putExtra("componentlist", componentlist);
				Collections.sort(markerlist,
						new Comparator<ConnectedComponent>() {
							@Override
							public int compare(ConnectedComponent cc1,
									ConnectedComponent cc2) {
								return cc1.top - cc2.top;
							}
						});
				goToNextActivity.putExtra("markerlist", markerlist);
				String origin = "Segmentation";
				goToNextActivity.putExtra("origin", origin);
				goToNextActivity.putExtra("analysisorigin", analysisorigin);
				startActivity(goToNextActivity);

			}
		});

		btPrev = (Button) findViewById(R.id.btPrev);
		btPrev.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// startActivity(new Intent(SegmentationActivity.this,
				// GaborActivity.class));
				startActivity(new Intent(SegmentationActivity.this,
						GaborActivity2.class));
			}
		});

		btCompare = (Button) findViewById(R.id.btCompare);
		btCompare.setEnabled(false);
		btCompare.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				try {
					// TODO Auto-generated method stub
					Intent goToNextActivity = new Intent(
							getApplicationContext(), CompareActivity.class);
					// goToNextActivity.putParcelableArrayListExtra("componentlist",
					// (ArrayList<? extends Parcelable>) componentlist);
					goToNextActivity.putExtra("componentlist", componentlist);
					// byte[] bytes;
					// bytes = compressImage(activeBmp);
					// byte[] bytes1;
					// bytes1 = compressImage(originalBmp);
					// goToNextActivity.putExtra("BMP1", bytes1);
					// goToNextActivity.putExtra("BMP", bytes);
					goToNextActivity.putExtra("componentlist", componentlist);
					Collections.sort(markerlist,
							new Comparator<ConnectedComponent>() {
								@Override
								public int compare(ConnectedComponent cc1,
										ConnectedComponent cc2) {
									return cc1.top - cc2.top;
								}
							});
					String origin = "Segmentation";
					goToNextActivity.putExtra("origin", origin);
					goToNextActivity.putExtra("markerlist", markerlist);
					startActivity(goToNextActivity);
				} catch (Exception e) {

					Toast.makeText(SegmentationActivity.this, e.toString(),
							Toast.LENGTH_SHORT);
					CharArrayWriter cw = new CharArrayWriter();
					PrintWriter w = new PrintWriter(cw);
					e.printStackTrace(w);
					w.close();
					String trace = cw.toString();

				}
			}
		});

	}

	// srcImg MUST be a BINARY image
	public void findConnectedComponents(Mat srcImg, Mat destImg,
			ArrayList<ConnectedComponent> connectedComponentList, int minArea) {
		Hashtable<Integer, ConnectedComponent> conCompHt = new Hashtable<Integer, ConnectedComponent>();// from
																										// label
																										// to
																										// connected
																										// component
		int[][] labelMatrix = new int[srcImg.height()][srcImg.width()]; // all
																		// elements
																		// will
																		// be
																		// initialized
																		// with
																		// 0
		int issuedLabel = 0;

		System.out.println("Start finding connected components...");

		int temp = 0;
		for (int i = 1; i < srcImg.height() - 1; i++) {
			for (int j = 1; j < srcImg.width() - 1; j++) {
				double[] data = srcImg.get(i, j);
				if (data[0] <= 50) { // black pixel
					// if(data[0] > 50){
					if (labelMatrix[i][j - 1] != 0) {// the left neighbour pixel
														// has label (and of
														// course is black
														// pixel)
						labelMatrix[i][j] = labelMatrix[i][j - 1]; // label
																	// pixel
																	// (i,j),
																	// and admit
																	// it to the
																	// left
																	// neighbor
																	// pixel's
																	// connected
																	// component
						// UPDATE THE CONNECTED COMPONENT
						ConnectedComponent conComp = conCompHt
								.get(labelMatrix[i][j - 1]);
						if (conComp == null) {
							System.out.println(i + "\t" + j + "\t"
									+ labelMatrix[i][j]);
							System.out.println(labelMatrix[i][j - 1]);
							/*
							 * for (int g= 12;g<26;g++){ for (int f= 540; f<560;
							 * f++){ System.out.print(srcImg.get(g, f)[0]+"\t");
							 * } System.out.println(); }
							 * 
							 * for (int g= 12;g<26;g++){ for (int f= 540; f<560;
							 * f++){ System.out.print(labelMatrix[g][f]+"\t"); }
							 * System.out.println(); }
							 */
						}
						conComp.noPixels++;
						if (conComp.right < j)
							conComp.right = j;// no need to update the left, top
												// and bottom boundaries of the
												// connected component
						conCompHt.put(labelMatrix[i][j - 1], conComp);

						// MERGING THE CONNECTED COMPONENT WITH ITS NEIGHBOUR
						// CONNECTED COMPONENTS (If existing any)
						ConnectedComponent neighbourConComp;
						if (labelMatrix[i - 1][j - 1] != 0
								&& labelMatrix[i - 1][j - 1] != labelMatrix[i][j - 1]) {
							temp = labelMatrix[i - 1][j - 1];
							for (int e = j - 1; e < srcImg.width(); e++) {// update
																			// the
																			// labels
																			// of
																			// all
																			// pixels
																			// at
																			// the
																			// same
																			// line
																			// and
																			// have
																			// the
																			// same
																			// label
																			// as
																			// pixel
																			// (i-1,j-1)
								if (labelMatrix[i - 1][e] == temp)
									labelMatrix[i - 1][e] = labelMatrix[i][j - 1];
							}
							for (int e = j - 2; e > 0; e--) {// update the
																// labels of all
																// pixels at the
																// same line as
																// pixel (i,j)
																// and have the
																// same label as
																// pixel
																// (i-1,j-1)
								if (labelMatrix[i][e] == temp)
									labelMatrix[i][e] = labelMatrix[i][j - 1];
							}

							neighbourConComp = conCompHt.get(temp);
							conComp.noPixels += neighbourConComp.noPixels;
							if (neighbourConComp.left < conComp.left)
								conComp.left = neighbourConComp.left;
							if (neighbourConComp.right > conComp.right)
								conComp.right = neighbourConComp.right;
							if (neighbourConComp.top < conComp.top)
								conComp.top = neighbourConComp.top;// no need to
																	// update
																	// the
																	// bottom
																	// boundary
							conCompHt.put(labelMatrix[i][j - 1], conComp);
							conCompHt.remove(temp);// delete the neighbour
													// conComp after it is
													// merged
						}
						if (labelMatrix[i - 1][j] != 0
								&& labelMatrix[i - 1][j] != labelMatrix[i][j - 1]) {
							temp = labelMatrix[i - 1][j];
							for (int e = j; e < srcImg.width(); e++) {// update
																		// the
																		// labels
																		// of
																		// all
																		// pixels
																		// at
																		// the
																		// same
																		// line
																		// and
																		// have
																		// the
																		// same
																		// label
																		// as
																		// pixel
																		// (i-1,j)
								if (labelMatrix[i - 1][e] == temp)
									labelMatrix[i - 1][e] = labelMatrix[i][j - 1];
							}
							for (int e = j - 2; e > 0; e--) {// update the
																// labels of all
																// pixels at the
																// same line as
																// pixel (i,j)
																// and have the
																// same label as
																// pixel (i-1,j)
								if (labelMatrix[i][e] == temp)
									labelMatrix[i][e] = labelMatrix[i][j - 1];
							}

							neighbourConComp = conCompHt.get(temp);
							conComp.noPixels += neighbourConComp.noPixels;
							if (neighbourConComp.left < conComp.left)
								conComp.left = neighbourConComp.left;
							if (neighbourConComp.right > conComp.right)
								conComp.right = neighbourConComp.right;
							if (neighbourConComp.top < conComp.top)
								conComp.top = neighbourConComp.top;// no need to
																	// update
																	// the
																	// bottom
																	// boundary
							conCompHt.put(labelMatrix[i][j - 1], conComp);

							conCompHt.remove(temp);// delete the neighbour
													// conComp after it is
													// merged
						}
						// Log.d("tag1", i + " " + j);
						if (labelMatrix[i - 1][j + 1] != 0
								&& labelMatrix[i - 1][j + 1] != labelMatrix[i][j - 1]) {
							temp = labelMatrix[i - 1][j + 1];
							for (int e = j + 1; e < srcImg.width(); e++) {// update
																			// the
																			// labels
																			// of
																			// all
																			// pixels
																			// at
																			// the
																			// same
																			// line
																			// and
																			// have
																			// the
																			// same
																			// label
																			// as
																			// pixel
																			// (i-1,j+1)
								if (labelMatrix[i - 1][e] == temp)
									labelMatrix[i - 1][e] = labelMatrix[i][j - 1];
							}
							for (int e = j - 2; e > 0; e--) {// update the
																// labels of all
																// pixels at the
																// same line as
																// pixel (i,j)
																// and have the
																// same label as
																// pixel
																// (i-1,j+1)
								if (labelMatrix[i][e] == temp)
									labelMatrix[i][e] = labelMatrix[i][j - 1];
							}

							neighbourConComp = conCompHt.get(temp);
							conComp.noPixels += neighbourConComp.noPixels;
							if (neighbourConComp.left < conComp.left)
								conComp.left = neighbourConComp.left;
							if (neighbourConComp.right > conComp.right)
								conComp.right = neighbourConComp.right;
							if (neighbourConComp.top < conComp.top)
								conComp.top = neighbourConComp.top;// no need to
																	// update
																	// the
																	// bottom
																	// boundary
							conCompHt.put(labelMatrix[i][j - 1], conComp);
							conCompHt.remove(temp);// delete the neighbour
													// conComp after it is
													// merged
						}
					} else if (labelMatrix[i - 1][j - 1] != 0) {// the top-left
																// neighbour
																// pixel has
																// label (and of
																// course is
																// black pixel)
						labelMatrix[i][j] = labelMatrix[i - 1][j - 1]; // label
																		// pixel
																		// (i,j),
																		// and
																		// admit
																		// it to
																		// the
																		// top-left
																		// neighbor
																		// pixel's
																		// connected
																		// component
						// UPDATE THE CONNECTED COMPONENT
						ConnectedComponent conComp = conCompHt
								.get(labelMatrix[i - 1][j - 1]);
						conComp.noPixels++;
						if (conComp.right < j)
							conComp.right = j;
						if (conComp.bottom < i)
							conComp.bottom = i;// no need to update the left and
												// top boundaries of the
												// connected component
						conCompHt.put(labelMatrix[i - 1][j - 1], conComp);

						// MERGING THE CONNECTED COMPONENT WITH ITS NEIGHBOUR
						// CONNECTED COMPONENTS (If existing any)
						ConnectedComponent neighbourConComp;
						if (labelMatrix[i - 1][j] != 0
								&& labelMatrix[i - 1][j] != labelMatrix[i - 1][j - 1]) {
							// This will never happen because
							// labelMatrix[i-1][j] must become equal to
							// labelMatrix[i-1][j-1]
							// when line (i-1) was scanned previously
						}
						if (labelMatrix[i - 1][j + 1] != 0
								&& labelMatrix[i - 1][j + 1] != labelMatrix[i - 1][j - 1]) {
							temp = labelMatrix[i - 1][j + 1];
							for (int e = j + 1; e < srcImg.width(); e++) {// update
																			// the
																			// labels
																			// of
																			// all
																			// pixels
																			// at
																			// the
																			// same
																			// line
																			// and
																			// have
																			// the
																			// same
																			// label
																			// as
																			// pixel
																			// (i-1,j+1)
								if (labelMatrix[i - 1][e] == temp)
									labelMatrix[i - 1][e] = labelMatrix[i - 1][j - 1];
							}
							for (int e = j - 2; e > 0; e--) {// update the
																// labels of all
																// pixels at the
																// same line as
																// pixel (i,j)
																// and have the
																// same label as
																// pixel
																// (i-1,j+1)
								if (labelMatrix[i][e] == temp)
									labelMatrix[i][e] = labelMatrix[i - 1][j - 1];
							}

							neighbourConComp = conCompHt.get(temp);
							conComp.noPixels += neighbourConComp.noPixels;
							if (neighbourConComp.left < conComp.left)
								conComp.left = neighbourConComp.left;
							if (neighbourConComp.right > conComp.right)
								conComp.right = neighbourConComp.right;
							if (neighbourConComp.top < conComp.top)
								conComp.top = neighbourConComp.top;// no need to
																	// update
																	// the
																	// bottom
																	// boundary
							conCompHt.put(labelMatrix[i][j - 1], conComp);
							conCompHt.remove(temp);// delete the neighbour
													// conComp after it is
													// merged
						}

					} else if (labelMatrix[i - 1][j] != 0) {// the top neighbour
															// pixel has label
															// (and of course is
															// black pixel)
						labelMatrix[i][j] = labelMatrix[i - 1][j]; // label
																	// pixel
																	// (i,j),
																	// and admit
																	// it to the
																	// top
																	// neighbour
																	// pixel's
																	// connected
																	// component
						// UPDATE THE CONNECTED COMPONENT
						ConnectedComponent conComp = conCompHt
								.get(labelMatrix[i - 1][j]);
						conComp.noPixels++;
						if (conComp.bottom < i)
							conComp.bottom = i;// no need to update the left,
												// right and top boundaries of
												// the connected component
						conCompHt.put(labelMatrix[i - 1][j], conComp);

						// MERGING THE CONNECTED COMPONENT WITH ITS NEIGHBOUR
						// CONNECTED COMPONENTS (If existing any)
						// ConnectedComponent neighbourConComp;
						if (labelMatrix[i - 1][j + 1] != 0
								&& labelMatrix[i - 1][j + 1] != labelMatrix[i - 1][j]) {
							// This will never happen because
							// labelMatrix[i-1][j+1] must become equal to
							// labelMatrix[i-1][j]
							// when line (i-1) was scanned previously
						}
					} else if (labelMatrix[i - 1][j + 1] != 0) {// the top-right
																// neighbour
																// pixel has
																// label (and of
																// course is
																// black pixel)
						labelMatrix[i][j] = labelMatrix[i - 1][j + 1]; // label
																		// pixel
																		// (i,j),
																		// and
																		// admit
																		// it to
																		// the
																		// top-right
																		// neighbour
																		// pixel's
																		// connected
																		// component
						// UPDATE THE CONNECTED COMPONENT
						ConnectedComponent conComp = conCompHt
								.get(labelMatrix[i - 1][j + 1]);
						conComp.noPixels++;
						if (conComp.bottom < i)
							conComp.bottom = i;// no need to update the left,
												// right and top boundaries of
												// the connected component
						if (conComp.left > j)
							conComp.left = j;
						conCompHt.put(labelMatrix[i - 1][j + 1], conComp);
					} else {// there is none black pixels among the 4 neighbour
							// pixels of pixel (i,j)
							// CREATE A NEW CONNECTED COMPONENT FOR pixel (i,j)
						issuedLabel++;
						labelMatrix[i][j] = issuedLabel;
						ConnectedComponent conComp = new ConnectedComponent();
						conComp.noPixels = 1;
						conComp.label = issuedLabel;
						conComp.left = conComp.right = j;
						conComp.top = conComp.bottom = i;
						conCompHt.put(labelMatrix[i][j], conComp);
					}
				}// end if (data[0]<=50){ //pixel (i,j) is black
			}// end for j
		}// end for i
		System.out.println("Finnished finding connected components.");

		// LISTING ALL THE CONNECTED COMPONENTS
		Enumeration<Integer> en = conCompHt.keys();
		int label = 0;
		while (en.hasMoreElements()) {
			label = en.nextElement();
			connectedComponentList.add(conCompHt.get(label));
		}
		// update the connectedcomponent to offset the gabor filtering
		for (int i = 0; i < connectedComponentList.size(); i++) {

			ConnectedComponent cc = connectedComponentList.get(i);
			/*
			 * if(GaborActivity2.sigmavalue >= sigmatochange) { //cc.top =
			 * cc.top - 12; //cc.bottom = cc.bottom - 12; cc.top = cc.top;
			 * cc.bottom = cc.bottom; } else { cc.top = cc.top + 12; cc.bottom =
			 * cc.bottom + 12; }
			 */
			// 8/9
			// cc.top = cc.top + 8;
			// cc.bottom = cc.bottom +8;

		}

		// DRAW ALL THE CONNECTED COMPONENTS TO destImg (using rectangle bounds)
		for (int i = 0; i < connectedComponentList.size(); i++) {
			if (connectedComponentList.get(i).noPixels >= minArea) {
				/*
				 * Core.rectangle(destImg, new Point(
				 * connectedComponentList.get(i).left,
				 * connectedComponentList.get(i).top), new Point(
				 * connectedComponentList.get(i).right,
				 * connectedComponentList.get(i).bottom), new Scalar(255, 0, 0),
				 * 2);
				 */
				if (connectedComponentList.get(i).bottom < originalBmp
						.getHeight()) {
					componentlist.add(connectedComponentList.get(i));
				} else {
					connectedComponentList.get(i).bottom = originalBmp
							.getHeight();
					componentlist.add(connectedComponentList.get(i));
				}
			}

		}

		System.out.println("Finnished drawing connected components.");
	}

	public void drawRectangles() {
		for (int i = 0; i < componentlist.size(); i++) {
			int top = componentlist.get(i).top;

			int bottom = componentlist.get(i).bottom;
			int left = componentlist.get(i).left;
			int right = componentlist.get(i).right;
			Core.rectangle(destImg, new Point(left, top), new Point(right,
					bottom), new Scalar(255, 0, 0), 2);

			int centerheight = (bottom + top) / 2;
			int centerwidth = (right + left) / 2;
			Point org = new Point(centerwidth, centerheight);
			Core.putText(destImg, "" + i, org, 3, 1, new Scalar(0, 0, 255), 5);

		}

		for (int j = 0; j < markerlist.size(); j++) {
			int top = markerlist.get(j).top;
			int bottom = markerlist.get(j).bottom;
			// int toptodisplay = 0;
			// int bottomtodisplay = 0;
			/*
			 * if(GaborActivity2.sigmavalue >= sigmatochange){ toptodisplay =
			 * top; bottomtodisplay = bottom; } else { toptodisplay = top - 12;
			 * bottomtodisplay = bottom - 12; }
			 */
			// 8/9
			// toptodisplay = top - 12;
			// bottomtodisplay = bottom - 12;

			int left = markerlist.get(j).left;
			int right = markerlist.get(j).right;
			Core.rectangle(destImg, new Point(left, top), new Point(right,
					bottom), new Scalar(255, 255, 0), 2);

			int centerheight = (bottom + top) / 2;
			Point org = new Point(right, centerheight);

			Core.putText(destImg, "" + j, org, 3, 1, new Scalar(0, 255, 0), 5);

		}

	}

	public void fixRectangles() {
		Mat srcImg = new Mat(grayBmp.getHeight(), grayBmp.getWidth(),
				CvType.CV_8U, new Scalar(4));
		Bitmap myBitmap32 = grayBmp.copy(Bitmap.Config.ARGB_8888, true);
		Utils.bitmapToMat(myBitmap32, srcImg);

		// get initial intensity average
		for (int i = 0; i < componentlist.size(); i++) {
			int averageFragmentIntensity = 0;
			int j = 0;
			int k = 0;

			for (j = 0; j + componentlist.get(i).left <= componentlist.get(i).right; j++) {
				for (k = 0; k + componentlist.get(i).top <= componentlist
						.get(i).bottom; k++) {
					// int intensity =
					// grayBmp.getPixel(componentlist.get(i).left + j,
					// componentlist.get(i).top + k);
					double[] intensity = srcImg.get(componentlist.get(i).top
							+ k, componentlist.get(i).left + j);
					averageFragmentIntensity += intensity[0];
				}
			}
			// test upwards first
			averageFragmentIntensity = averageFragmentIntensity
					/ ((componentlist.get(i).right - componentlist.get(i).left) * (componentlist
							.get(i).bottom - componentlist.get(i).top));
			upwardsTest(averageFragmentIntensity, componentlist.get(i), srcImg);
			Log.d("tag1",
					"component: " + i + " top: " + componentlist.get(i).top
							+ " bottom: " + componentlist.get(i).bottom);
			downwardsTest(averageFragmentIntensity, componentlist.get(i),
					srcImg);
		}
		/*
		 * for (int i = 0; i < markerlist.size(); i++) { int
		 * averageFragmentIntensity = 0; int j = 0; int k = 0;
		 * 
		 * for (j = 0; j + markerlist.get(i).left <= markerlist.get(i).right;
		 * j++) { for (k = 0; k + markerlist.get(i).top <=
		 * markerlist.get(i).bottom; k++) { // int intensity = //
		 * grayBmp.getPixel(componentlist.get(i).left + j, //
		 * componentlist.get(i).top + k); double[] intensity =
		 * srcImg.get(markerlist.get(i).top + k, markerlist.get(i).left + j);
		 * averageFragmentIntensity += intensity[0]; } } // test upwards first
		 * averageFragmentIntensity = averageFragmentIntensity /
		 * ((markerlist.get(i).right - markerlist.get(i).left) * (markerlist
		 * .get(i).bottom - markerlist.get(i).top));
		 * upwardsTest(averageFragmentIntensity, markerlist.get(i), srcImg);
		 * downwardsTest(averageFragmentIntensity, markerlist.get(i), srcImg); }
		 */
	}

	private void upwardsTest(int initialavg, ConnectedComponent cc, Mat srcImg) {
		boolean status = false;
		int initialtestavg = initialavg;

		while (status != true) {
			// initial moving up of one pixel
			cc.top -= 1;
			cc.bottom -= 1;
			int testavg = 0;
			int j = 0;
			int k = 0;
			for (j = 0; j + cc.left <= cc.right; j++) {

				for (k = 0; k + cc.top <= cc.bottom; k++) {
					if (k + cc.top > 0) {
						double[] intensity = srcImg
								.get(cc.top + k, cc.left + j);
						testavg += intensity[0];
					} else {
						status = true;
						break;
					}
				}

			}
			testavg = testavg / ((cc.right - cc.left) * (cc.bottom - cc.top));
			if (testavg <= initialtestavg) {
				initialtestavg = testavg;
				status = false;
			} else {
				status = true;
			}
		}
	}

	private void downwardsTest(int initialavg, ConnectedComponent cc, Mat srcImg) {
		boolean status = false;
		int initialtestavg = initialavg;

		while (status != true) {
			// initial moving up of one pixel
			cc.top += 1;
			cc.bottom += 1;
			int testavg = 0;
			int j = 0;
			int k = 0;

			for (j = 0; j + cc.left <= cc.right; j++) {
				for (k = 0; k + cc.top <= cc.bottom; k++) {
					if (k + cc.top <= srcImg.height()) {
						double[] intensity = srcImg
								.get(cc.top + k, cc.left + j);
						testavg += intensity[0];
					} else {
						status = true;
						break;
					}
				}

			}
			testavg = testavg / ((cc.right - cc.left) * (cc.bottom - cc.top));
			if (cc.bottom + 1 >= grayBmp.getHeight()) {
				status = true;
			} else {
				if (testavg <= initialtestavg) {
					initialtestavg = testavg;
					status = false;
				} else {
					status = true;
				}
			}
		}
	}

	public void fixRectangles2() {
		Mat srcImg = new Mat(grayBmp.getHeight(), grayBmp.getWidth(),
				CvType.CV_8U, new Scalar(4));
		Bitmap myBitmap32 = grayBmp.copy(Bitmap.Config.ARGB_8888, true);
		Utils.bitmapToMat(myBitmap32, srcImg);

		ArrayList intensityList = new ArrayList();
		int averageFragmentIntensity = 0;
		for (int i = 0; i < componentlist.size(); i++) {
			for (int j = 0; j + componentlist.get(i).top <= componentlist
					.get(i).bottom; j++) {
				int rowintensity = 0;
				for (int k = 0; k + componentlist.get(i).left <= componentlist
						.get(i).right; k++) {
					double[] intensity = srcImg.get(componentlist.get(i).top,
							componentlist.get(i).left + k);
					rowintensity += intensity[0];
				}
				intensityList.add(rowintensity);
				averageFragmentIntensity += rowintensity;
			}

			averageFragmentIntensity = averageFragmentIntensity
					/ ((componentlist.get(i).right - componentlist.get(i).left) * (componentlist
							.get(i).bottom - componentlist.get(i).top));

			// test upwards
			upwardsTest2(intensityList, averageFragmentIntensity,
					componentlist.get(i), srcImg);
			downwardsTest2(intensityList, averageFragmentIntensity,
					componentlist.get(i), srcImg);

		}

	}

	private void upwardsTest2(ArrayList initialintensitylist,
			int averageFragmentIntensity, ConnectedComponent cc, Mat srcImg) {
		boolean status = false;
		ArrayList testintensitylist = initialintensitylist;
		// test fragmentIntensity with testfragmentIntensity
		int testfragmentIntensity = averageFragmentIntensity;
		while (status != true) {
			int fragmentIntensity = 0;
			cc.top -= 1;
			cc.bottom -= 1;

			int rowintensity = 0;
			for (int k = 0; k + cc.left <= cc.right; k++) {
				double[] intensity = srcImg.get(cc.top, cc.left + k);
				rowintensity += intensity[0];
			}
			// upwards add top
			testintensitylist.add(0, rowintensity);
			// upwards remove bottom
			testintensitylist.remove(testintensitylist.size() - 1);
			fragmentIntensity += (Integer) testintensitylist.get(0);
			fragmentIntensity -= (Integer) testintensitylist
					.get(testintensitylist.size() - 1);

			// average
			fragmentIntensity = fragmentIntensity
					/ ((cc.right - cc.left) * (cc.bottom - cc.top));
			// if brighter, continue to loop
			if (fragmentIntensity <= testfragmentIntensity) {
				// replace testfragmentIntensity with fragmentIntensity
				testfragmentIntensity = fragmentIntensity;
				status = false;
			} else {
				status = true;
			}

		}
	}

	private void downwardsTest2(ArrayList initialintensitylist,
			int averageFragmentIntensity, ConnectedComponent cc, Mat srcImg) {
		boolean status = false;
		ArrayList testintensitylist = initialintensitylist;
		// test fragmentIntensity with testfragmentIntensity
		int testfragmentIntensity = averageFragmentIntensity;
		while (status != true) {
			int fragmentIntensity = 0;
			cc.top += 1;
			cc.bottom += 1;

			int rowintensity = 0;
			for (int k = 0; k + cc.left <= cc.right; k++) {
				// reverse the calculation
				double[] intensity = srcImg.get(cc.bottom, cc.left + k);
				rowintensity += intensity[0];
			}
			// downwards add bottom
			testintensitylist.add(rowintensity);
			// downwards remove top
			testintensitylist.remove(0);
			fragmentIntensity += (Integer) testintensitylist
					.get(testintensitylist.size() - 1);
			fragmentIntensity -= (Integer) testintensitylist.get(0);
			// average
			fragmentIntensity = fragmentIntensity
					/ ((cc.right - cc.left) * (cc.bottom - cc.top));
			// if darker, continue to loop
			if (fragmentIntensity <= testfragmentIntensity) {
				// replace testfragmentIntensity with fragmentIntensity
				testfragmentIntensity = fragmentIntensity;
				status = false;
			} else {
				status = true;
			}
		}

	}

	public void fixRectangles3() {
		Mat srcImg = new Mat(grayBmp.getHeight(), grayBmp.getWidth(),
				CvType.CV_8U, new Scalar(4));
		Bitmap myBitmap32 = grayBmp.copy(Bitmap.Config.ARGB_8888, true);
		Utils.bitmapToMat(myBitmap32, srcImg);

		ArrayList intensityList = new ArrayList();
		int averageFragmentIntensity = 0;
		for (int i = 0; i < componentlist.size(); i++) {
			for (int j = 0; j + componentlist.get(i).top <= componentlist
					.get(i).bottom; j++) {
				int rowintensity = 0;
				for (int k = 0; k + componentlist.get(i).left <= componentlist
						.get(i).right; k++) {
					double[] intensity = srcImg.get(componentlist.get(i).top,
							componentlist.get(i).left + k);
					rowintensity += intensity[0];
				}
				intensityList.add(rowintensity);
				averageFragmentIntensity += rowintensity;
			}

			// averageFragmentIntensity = averageFragmentIntensity
			// / ((componentlist.get(i).right - componentlist.get(i).left) *
			// (componentlist
			// .get(i).bottom - componentlist.get(i).top));

			// test upwards
			int upresult = upwardsTest3(intensityList,
					averageFragmentIntensity, componentlist.get(i), srcImg);
			int downresult = downwardsTest3(intensityList,
					averageFragmentIntensity, componentlist.get(i), srcImg);
			if (upresult < downresult) {
				componentlist.get(i).top -= counterup;
				componentlist.get(i).bottom -= counterup;
			} else if (upresult == downresult) {
				if (counterup < counterdown) {
					componentlist.get(i).top -= counterup;
					componentlist.get(i).bottom -= counterup;
				} else {
					componentlist.get(i).top += counterdown;
					componentlist.get(i).bottom += counterdown;
				}
			} else {
				componentlist.get(i).top += counterdown;
				componentlist.get(i).bottom += counterdown;
			}
		}

	}

	private int upwardsTest3(ArrayList initialintensitylist,
			int averageFragmentIntensity, ConnectedComponent cc, Mat srcImg) {
		boolean status = false;
		ArrayList testintensitylist = initialintensitylist;
		// test fragmentIntensity with testfragmentIntensity
		int testfragmentIntensity = averageFragmentIntensity;
		int fragmentIntensity = averageFragmentIntensity;
		while (status != true) {
			fragmentIntensity = testfragmentIntensity;
			counterup++;

			int rowintensity = 0;
			for (int k = 0; k + cc.left <= cc.right; k++) {
				if (cc.top - counterup >= 0) {
					double[] intensity = srcImg.get(cc.top - counterup, cc.left
							+ k);
					rowintensity += intensity[0];
				} else {
					status = true;
				}

			}
			// upwards add top
			testintensitylist.add(0, rowintensity);
			// upwards remove bottom
			testintensitylist.remove(testintensitylist.size() - 1);
			fragmentIntensity += (Integer) testintensitylist.get(0);
			fragmentIntensity -= (Integer) testintensitylist
					.get(testintensitylist.size() - 1);
			int compareintensity1 = fragmentIntensity
					/ ((cc.right - cc.left) * (cc.bottom - cc.top));
			int compareintensity2 = testfragmentIntensity
					/ ((cc.right - cc.left) * (cc.bottom - cc.top));

			if (compareintensity1 <= compareintensity2) {
				// replace testfragmentIntensity with fragmentIntensity
				testfragmentIntensity = fragmentIntensity;
				status = false;
			} else {
				status = true;
			}
		}
		return testfragmentIntensity;
	}

	private int downwardsTest3(ArrayList initialintensitylist,
			int averageFragmentIntensity, ConnectedComponent cc, Mat srcImg) {
		boolean status = false;
		ArrayList testintensitylist = initialintensitylist;
		int testfragmentIntensity = averageFragmentIntensity;
		int fragmentIntensity = averageFragmentIntensity;
		while (status != true) {
			fragmentIntensity = testfragmentIntensity;
			counterdown++;

			int rowintensity = 0;
			for (int k = 0; k + cc.left <= cc.right; k++) {
				// reverse the calculation
				if (cc.top + counterdown <= grayBmp.getHeight()) {
					double[] intensity = srcImg.get(cc.bottom + counterdown,
							cc.left + k);
					rowintensity += intensity[0];
				} else {
					status = true;
				}
			}
			// downwards add bottom
			testintensitylist.add(rowintensity);
			// downwards remove top
			testintensitylist.remove(0);
			fragmentIntensity += (Integer) testintensitylist
					.get(testintensitylist.size() - 1);
			fragmentIntensity -= (Integer) testintensitylist.get(0);

			int compareintensity1 = fragmentIntensity
					/ ((cc.right - cc.left) * (cc.bottom - cc.top));
			int compareintensity2 = testfragmentIntensity
					/ ((cc.right - cc.left) * (cc.bottom - cc.top));

			if (compareintensity1 <= compareintensity2) {
				// replace testfragmentIntensity with fragmentIntensity
				testfragmentIntensity = fragmentIntensity;
				status = false;
			} else {
				status = true;

			}
		}
		return testfragmentIntensity;

	}

	@Override
	public void onBackPressed() {
		// TODO Auto-generated method stub
		super.onBackPressed();
		// Intent returnActivity = new Intent(this, GaborActivity.class);
		Intent returnActivity = new Intent(this, GaborActivity2.class);
		startActivity(returnActivity);
	}

	public byte[] compressImage(Bitmap image) {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.PNG, 0, stream);
		byte[] bytes = stream.toByteArray();
		return bytes;
	}

	private void fixLongfragments(int medianwidth, ConnectedComponent cc) {
		int ccwidth = cc.right - cc.left;
		if (ccwidth > medianwidth) {
			int expectedwidthcount = Math.round(ccwidth / medianwidth); // cannot
																		// include
																		// cc
																		// itself
			int expectedwidth = Math.round(ccwidth / expectedwidthcount);
			if (expectedwidthcount > 1) {
				cc.right = cc.left + expectedwidth;
				ConnectedComponent ccnew = new ConnectedComponent();
				for (int i = 0; i < expectedwidthcount - 1; i++) {
					if (i == 0) {
						ccnew.top = cc.top;
						ccnew.bottom = cc.bottom;
						ccnew.left = cc.right;
						ccnew.right = ccnew.left + expectedwidth;
						// add to addedcomponentlist, then add
						// addedcomponentlist objects into componentlist
						addedcomponentlist.add(ccnew);
					} else {
						ccnew.top = ccnew.top;
						ccnew.bottom = ccnew.bottom;
						ccnew.left = ccnew.right;
						ccnew.right = ccnew.left + expectedwidth;
						addedcomponentlist.add(ccnew);
					}
				}
			} else {

			}
		}
	}

	private void segmentPicture() {

		boolean progress = false;

		takenBmp = originalBmp;
		Mat srcImg = new Mat(takenBmp.getHeight(), takenBmp.getWidth(),
				CvType.CV_8U, new Scalar(4));
		int ch = srcImg.channels();
		Utils.bitmapToMat(takenBmp, srcImg);
		Imgproc.cvtColor(srcImg, srcImg, Imgproc.COLOR_BGR2GRAY);
		ch = srcImg.channels();
		ArrayList<ConnectedComponent> connectedComponentList = new ArrayList<ConnectedComponent>();
		destImg = new Mat();
		Imgproc.cvtColor(srcImg, destImg, Imgproc.COLOR_GRAY2BGR);

		int w = srcImg.width();
		int h = srcImg.height();

		minsize = Integer.parseInt(etMinsize.getText().toString());
		componentlist.clear();
		connectedComponentList.clear();
		markerlist.clear();
		findConnectedComponents(srcImg, destImg, connectedComponentList,
				minsize);

		Collections.sort(componentlist, new Comparator<ConnectedComponent>() {
			@Override
			public int compare(ConnectedComponent cc1, ConnectedComponent cc2) {
				return cc1.left - cc2.left;
			}
		});

		// grey img
		grayBmp = RotationActivity.colorBmp.copy(Config.ARGB_8888, true);
		srcImg = new Mat(grayBmp.getHeight(), grayBmp.getWidth(), CvType.CV_8U,
				new Scalar(4));
		Bitmap myBitmap32 = grayBmp.copy(Bitmap.Config.ARGB_8888, true);
		Utils.bitmapToMat(myBitmap32, srcImg);
		Imgproc.cvtColor(srcImg, destImg, Imgproc.COLOR_BGR2GRAY);
		// grayBmp = Bitmap.createBitmap(destImg.cols(),
		// destImg.rows(),
		// Bitmap.Config.RGB_565);
		Utils.matToBitmap(destImg, grayBmp);
		fixRectangles();
		// fixRectangles3();

		MarkerStandard ms = StartActivity.ms;
		/*
		 * // 15 september, long fragment algorithm int medianfragnum =
		 * ms.getmarkers().size(); ArrayList<ConnectedComponent> medianfragments
		 * = new ArrayList<ConnectedComponent>(); for (int i = 0; i <
		 * medianfragnum; i++) { medianfragments.add(componentlist.get(i)); }
		 * Collections.sort(medianfragments, new
		 * Comparator<ConnectedComponent>() {
		 * 
		 * @Override public int compare(ConnectedComponent cc1,
		 * ConnectedComponent cc2) { return ((cc1.right - cc1.left) - (cc2.right
		 * - cc2.left)); } });
		 * 
		 * for (int i = 0; i < medianfragments.size(); i++) { Log.d("tag1",
		 * "median widths: " + (medianfragments.get(i).right - medianfragments
		 * .get(i).left)); } int medianwidth =
		 * medianfragments.get(medianfragments .size() / 2).right -
		 * medianfragments.get(medianfragments.size() / 2).left;
		 * 
		 * for (int i = 0; i < componentlist.size(); i++) {
		 * fixLongfragments(medianwidth, componentlist.get(i)); }
		 * 
		 * for (int i = 0; i < addedcomponentlist.size(); i++) {
		 * componentlist.add(addedcomponentlist.get(i)); }
		 * 
		 * // 15 september, long fragment algorithm
		 */

		ArrayList<ConnectedComponent> componentmarkers = new ArrayList<ConnectedComponent>();

		if (ms.getmarkers().size() < componentlist.size()) {
			for (int i = 0; i < ms.getmarkers().size() + 1; i++) {
				// for (int i = 0; i < 8; i++) {
				componentmarkers.add(componentlist.get(i));
			}

		}

		double graphaverage = 9999;
		double thresholdvalue = 30;

		Point pt1 = null;
		Point pt2 = null;

		while (graphaverage > thresholdvalue) {
			graphaverage = 0;
			ConnectedComponent mincc = new ConnectedComponent();
			mincc.top = 9999;

			ConnectedComponent maxcc = new ConnectedComponent();
			maxcc.top = 0;

			for (int i = 0; i < componentmarkers.size(); i++) {
				if (componentmarkers.get(i).top < mincc.top) {
					mincc = componentmarkers.get(i);
				}
				if (componentmarkers.get(i).top > maxcc.top) {
					maxcc = componentmarkers.get(i);
				}
			}

			// formula of line
			double m1 = 0, m2 = 0, m3 = 0, m4 = 0;
			for (int i = 0; i < componentmarkers.size(); i++) {
				double mlx = (componentmarkers.get(i).left + componentmarkers
						.get(i).right) / 2;
				double mly = (componentmarkers.get(i).top + componentmarkers
						.get(i).bottom) / 2;
				// m1 += mlx * mlx;
				// m2 += mlx * mly;
				// m3 += mlx;
				// m4 += mly;
				m1 += mly * mly;
				m2 += mlx * mly;
				m3 += mly;
				m4 += mlx;
			}

			double XMean = m3 / componentmarkers.size();
			double YMean = m4 / componentmarkers.size();
			double formulaA = (m2 - m3 * YMean) / (m1 - m3 * XMean);
			double formulaB = YMean - formulaA * XMean;

			int firstx = (mincc.left + mincc.right) / 2;
			int firsty = (mincc.top + mincc.bottom) / 2;
			int lastx = (maxcc.left + maxcc.right) / 2;
			int lasty = (maxcc.top + maxcc.bottom) / 2;

			double bestfity1 = firsty;
			double bestfitx1 = formulaA * bestfity1 + formulaB;// (bestfity1
																// -
																// formulaB)
																// /
																// formulaA;
			double bestfity2 = lasty;
			double bestfitx2 = formulaA * bestfity2 + formulaB;// (bestfity2
																// -
																// formulaB)
																// /
																// formulaA;

			pt1 = new Point(bestfitx1, bestfity1);
			pt2 = new Point(bestfitx2, bestfity2);
			for (int i = componentmarkers.size() - 1; i > -1; i--) {

				double jx = (componentmarkers.get(i).left + componentmarkers
						.get(i).right) / 2;
				double jy = (componentmarkers.get(i).top + componentmarkers
						.get(i).bottom) / 2;

				// double jbestfitx = (jy - formulaB) / formulaA;
				double jbestfitx = formulaA * jy + formulaB;
				;
				double componentaverage = Math.abs(jx - jbestfitx);
				graphaverage += componentaverage;
			}

			if (graphaverage > thresholdvalue) {
				Log.d("tag1", "deleted: " + (componentmarkers.size() - 1));
				componentmarkers.remove(componentmarkers.size() - 1);
			}

			Core.line(destImg, pt1, pt2, new Scalar(255, 0, 255), 5);

		}

		for (int i = 0; i < componentmarkers.size(); i++) {

			markerlist.add(componentmarkers.get(i));
		}

		Log.d("tag1", "markerlist size: " + markerlist.size());

		for (int i = markerlist.size() - 1; i >= 0; i--) {
			componentlist.remove(i);
		}

		// Core.line(destImg, pt1, pt2, new Scalar(255, 0, 0), 5);
		Bitmap drawnbmp = Bitmap.createBitmap(destImg.cols(), destImg.rows(),
				Bitmap.Config.RGB_565);
		Utils.matToBitmap(destImg, drawnbmp);

		Bitmap segmentedBmp = Bitmap.createBitmap(destImg.cols(),
				destImg.rows(), Bitmap.Config.RGB_565);
		Utils.matToBitmap(destImg, segmentedBmp);
		activeBmp = segmentedBmp;

		// ivImage.setEnabled(true);
		// btCompare.setEnabled(true);

		grayBmp = RotationActivity.colorBmp.copy(Config.ARGB_8888, true);
		Utils.bitmapToMat(grayBmp, destImg);

		drawRectangles();
		Utils.matToBitmap(destImg, grayBmp);
		activeBmp = grayBmp;
		// Utils.matToBitmap(destImg, grayBmp);
		// Bitmap resizedbmp1 = Bitmap.createScaledBitmap(grayBmp, 300,
		// 300, true);
		// ivImage.setImageBitmap(segmentedBmp);
		dialog.dismiss();

	}

}
